package online.dgyj.iot;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.nle.mylibrary.claimer.connector.ConnectorListener;
import com.nle.mylibrary.databus.DataBusFactory;
import com.nle.mylibrary.device.GenericConnector;
import com.nle.mylibrary.device.listener.ConnectResultListener;

import java.util.concurrent.TimeUnit;

@SuppressLint("DefaultLocale")
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Handler handler = new Handler(Looper.getMainLooper());
    private String iotIP;
    private int iotPort;
    private GenericConnector genericConnector;  // 通用连接器
    private Thread iotDIThread, iotAIThread;
    private boolean RTULink = false;

    private TextView IOTIPText, IOTPortText, DI1Val, DI2Val, DI3Val, DI4Val, DI5Val, DI6Val, DI7Val, DI8Val, AI1Val, AI2Val, AI3Val;
    private EditText IotIPEdit, IotPortEdit;
    private Switch LinkTypeSwitch;
    private Button LinkBtn, SetDOBtn;
    private Spinner DOSpinner, DOValueSpinner;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

        bind(); // 实例化控件
    }


    /**
     * 实例化控件
     */
    void bind() {
        IOTIPText = findViewById(R.id.IOTIPText);
        IOTPortText = findViewById(R.id.IOTPortText);
        DI1Val = findViewById(R.id.DI1Val);
        DI2Val = findViewById(R.id.DI2Val);
        DI3Val = findViewById(R.id.DI3Val);
        DI4Val = findViewById(R.id.DI4Val);
        DI5Val = findViewById(R.id.DI5Val);
        DI6Val = findViewById(R.id.DI6Val);
        DI7Val = findViewById(R.id.DI7Val);
        DI8Val = findViewById(R.id.DI8Val);
        AI1Val = findViewById(R.id.AI1Val);
        AI2Val = findViewById(R.id.AI2Val);
        AI3Val = findViewById(R.id.AI3Val);
        LinkTypeSwitch = findViewById(R.id.LinkTypeSwitch);
        LinkBtn = findViewById(R.id.LinkBtn);
        SetDOBtn = findViewById(R.id.SetDOBtn);
        DOSpinner = findViewById(R.id.DOSpinner);
        DOValueSpinner = findViewById(R.id.DOValueSpinner);
        IotIPEdit = findViewById(R.id.IotIPEdit);
        IotPortEdit = findViewById(R.id.IotPortEdit);

        LinkBtn.setOnClickListener(this);
        SetDOBtn.setOnClickListener(this);

        // Switch点击事件处理 (切换连接模式)
        LinkTypeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                RTULink = isChecked;
                if (RTULink) {
                    IOTIPText.setText("IOT SerialName:");
                    IOTPortText.setText("IOT Baud:");
                    IotIPEdit.setText("");
                    IotPortEdit.setText("");
                } else {
                    IOTIPText.setText("IOT IP:");
                    IOTPortText.setText("IOT Port:");
                    IotIPEdit.setText("");
                    IotPortEdit.setText("");
                }
            }
        });
    }

    /**
     * 点击事件处理
     *
     * @param v The view that was clicked.
     */
    @Override
    public void onClick(View v) {
        // 连接按钮处理
        if (v.getId() == R.id.LinkBtn) {
            // 判断是否建立连接
            if (genericConnector == null) {
                // 读取输入的IP与Port
                iotIP = IotIPEdit.getText().toString();
                iotPort = Integer.parseInt(IotPortEdit.getText().toString());

                // 禁用控件
                IotIPEdit.setEnabled(false);
                IotPortEdit.setEnabled(false);
                LinkTypeSwitch.setEnabled(false);

                if (RTULink) {
                    // 初始化子线程
                    iotDIThread = get_RTU_DI_Value();
                    iotAIThread = get_RTU_AI_Value(3);
                    // 串口连接
                    IOT_RTULInk();
                } else {
                    // 初始化子线程
                    iotDIThread = get_DI_Value();
                    iotAIThread = get_AI_Value(3);
                    // TCP连接
                    IOT_TCPLink();
                }
            } else {
                iotDIThread.interrupt();
                iotAIThread.interrupt();

                // 启用控件
                IotIPEdit.setEnabled(true);
                IotPortEdit.setEnabled(true);
                LinkTypeSwitch.setEnabled(true);

                LinkBtn.setText("Link");

                // 销毁
                genericConnector.stopConnect();
                genericConnector = null;
            }
        }
        // 控制IOT DO
        else if (v.getId() == R.id.SetDOBtn) {
            // 判断是否连接
            if (genericConnector == null) {
                Toast.makeText(this, "未连接", Toast.LENGTH_SHORT).show();
            } else {
                setDO().start();    // 控制DO
            }

        }
    }

    /**
     * TCP连接IOT
     */
    private void IOT_TCPLink() {
        // 建立连接
        genericConnector = new GenericConnector(DataBusFactory.newSocketDataBus(iotIP, iotPort), new ConnectResultListener() {
            @Override
            public void onConnectResult(boolean b) {
                if (b) {

                    Log.i("IotRtuStatus", "Link OK");

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplication(), "连接成功", Toast.LENGTH_SHORT).show();
                            LinkBtn.setText("DISC");
                        }
                    });

                    // 开启数据更新线程
                    iotAIThread.start();
                    iotDIThread.start();

                } else {
                    Log.i("IotRtuStatus", "Link Error");
                    // 销毁
                    genericConnector = null;

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            // 启用控件
                            IotIPEdit.setEnabled(true);
                            IotPortEdit.setEnabled(true);
                            LinkTypeSwitch.setEnabled(true);

                            LinkBtn.setText("Link");

                            Toast.makeText(getApplicationContext(), "连接失败", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        });
    }

    /**
     * 串口连接IOT
     */
    private void IOT_RTULInk() {
        // 建立连接
        genericConnector = new GenericConnector(DataBusFactory.newSerialDataBus(Integer.parseInt(iotIP), iotPort), new ConnectResultListener() {
            @Override
            public void onConnectResult(boolean b) {
                if (b) {
                    Log.i("IotTCPStatus", "Link OK");

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplication(), "连接成功", Toast.LENGTH_SHORT).show();
                            LinkBtn.setText("DISC");
                        }
                    });

                    iotAIThread.start();
                    iotDIThread.start();
                } else {
                    Log.i("IotTCPStatus", "Link Error");
                    // 销毁
                    genericConnector = null;

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            // 启用控件
                            IotIPEdit.setEnabled(true);
                            IotPortEdit.setEnabled(true);
                            LinkTypeSwitch.setEnabled(true);

                            LinkBtn.setText("Link");

                            Toast.makeText(getApplicationContext(), "连接失败", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        });
    }

    /**
     * 获取IOTDI口数据(TCP)
     *
     * @return 子线程
     */
    private Thread get_DI_Value() {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                    while (!Thread.currentThread().isInterrupted()) {
                        try {
                            genericConnector.sendTCPReadDI(1, new ConnectorListener() {
                                @Override
                                public void onSuccess(boolean b) {
                                    // 输出数据
                                    try {
                                        Log.i("Data 0", String.valueOf(genericConnector.getTCPReadDI().getDI0()));
                                        Log.i("Data 1", String.valueOf(genericConnector.getTCPReadDI().getDI1()));
                                        Log.i("Data 2", String.valueOf(genericConnector.getTCPReadDI().getDI2()));
                                        Log.i("Data 3", String.valueOf(genericConnector.getTCPReadDI().getDI3()));
                                        Log.i("Data 4", String.valueOf(genericConnector.getTCPReadDI().getDI4()));
                                        Log.i("Data 5", String.valueOf(genericConnector.getTCPReadDI().getDI5()));
                                        Log.i("Data 6", String.valueOf(genericConnector.getTCPReadDI().getDI6()));
                                        Log.i("Data 7", String.valueOf(genericConnector.getTCPReadDI().getDI7()));
                                    } catch (Exception e) {
                                        Log.e("Data Error", e.toString());
                                    }

                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            try {
                                                DI1Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI0()));
                                                DI2Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI1()));
                                                DI3Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI2()));
                                                DI4Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI3()));
                                                DI5Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI4()));
                                                DI6Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI5()));
                                                DI7Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI6()));
                                                DI8Val.setText(String.valueOf(genericConnector.getTCPReadDI().getDI7()));
                                            } catch (Exception e) {
                                                Log.e("Data Error", e.toString());
                                            }
                                        }
                                    });

                                }

                                @Override
                                public void onFail(Exception e) {

                                }
                            });
                            TimeUnit.SECONDS.sleep(1);
                        } catch (Exception e) {
                            Log.e("Get DI Error", e.toString());
                            break;
                        }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 获取IOTDI口数据(RTU)
     *
     * @return 子线程
     */
    private Thread get_RTU_DI_Value() {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                    while (!Thread.currentThread().isInterrupted()) {
                        try {
                            genericConnector.sendRtuReadDI(1, new ConnectorListener() {
                                @Override
                                public void onSuccess(boolean b) {
                                    try {
                                        Log.i("Data 0", String.valueOf(genericConnector.getRtuReadDI().getDI0()));
                                        Log.i("Data 1", String.valueOf(genericConnector.getRtuReadDI().getDI1()));
                                        Log.i("Data 2", String.valueOf(genericConnector.getRtuReadDI().getDI2()));
                                        Log.i("Data 3", String.valueOf(genericConnector.getRtuReadDI().getDI3()));
                                        Log.i("Data 4", String.valueOf(genericConnector.getRtuReadDI().getDI4()));
                                        Log.i("Data 5", String.valueOf(genericConnector.getRtuReadDI().getDI5()));
                                        Log.i("Data 6", String.valueOf(genericConnector.getRtuReadDI().getDI6()));
                                        Log.i("Data 7", String.valueOf(genericConnector.getRtuReadDI().getDI7()));
                                    } catch (Exception e) {
                                        Log.e("Data", e.toString());
                                    }

                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            try {
                                                DI1Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI0()));
                                                DI2Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI1()));
                                                DI3Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI2()));
                                                DI4Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI3()));
                                                DI5Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI4()));
                                                DI6Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI5()));
                                                DI7Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI6()));
                                                DI8Val.setText(String.valueOf(genericConnector.getRtuReadDI().getDI7()));
                                            } catch (Exception e) {
                                                Log.e("Data", e.toString());
                                            }
                                        }
                                    });

                                }

                                @Override
                                public void onFail(Exception e) {

                                }
                            });
                            TimeUnit.SECONDS.sleep(1);
                        } catch (Exception e) {
                            Log.e("Get DI Error", e.toString());
                            break;
                        }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 获取IOTAI口数据(TCP)
     *
     * @param codeNum 要读取的AI口数量
     * @return 子线程
     */
    private Thread get_AI_Value(int codeNum) {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        for (int i = 0; i < codeNum; i++) {
                            int cache = i;
                            // 请求AI口数据
                            genericConnector.sendTCPgetIOTVirtData(1, 2 * i, new ConnectorListener() {
                                @Override
                                public void onSuccess(boolean b) {

                                    /*   修改此处，在这里处理数据   */
                                    if (genericConnector.getTCPIOTVirtData() > 0) {
                                        switch (cache) {
                                            case 0:
                                                // 处理湿度并输出
                                                Log.i("AI1 Data", String.valueOf(6.25 * genericConnector.getTCPIOTVirtData() / 1000 - 25));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI1Val.setText(String.format("%.2f", 6.25 * genericConnector.getTCPIOTVirtData() / 1000 - 25));
                                                    }
                                                });
                                                break;
                                            case 1:
                                                // 处理温度并输出
                                                Log.i("AI2 Data", String.valueOf(4.375 * genericConnector.getTCPIOTVirtData() / 1000 - 27.5));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI2Val.setText(String.format("%.2f", 4.375 * genericConnector.getTCPIOTVirtData() / 1000 - 27.5));
                                                    }
                                                });
                                                break;
                                            case 2:
                                                // 输出AI3原始数据
                                                Log.i("AI3 Data", String.valueOf(genericConnector.getTCPIOTVirtData()));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI3Val.setText(String.valueOf(genericConnector.getTCPIOTVirtData()));
                                                    }
                                                });
                                                break;
                                        }
                                    }
                                }

                                @Override
                                public void onFail(Exception e) {

                                }
                            });
                            TimeUnit.SECONDS.sleep(1);
                        }
                        TimeUnit.SECONDS.sleep(1);
                    } catch (Exception e) {
                        Log.e("GetAI", e.toString());
                        break;
                    }
                }
            }
        });
    }

    /**
     * 获取IOTAI口数据(RTU)
     *
     * @param codeNum 要读取的AI口数量
     * @return 子线程
     */
    private Thread get_RTU_AI_Value(int codeNum) {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        for (int i = 0; i < codeNum; i++) {
                            int cache = i;
                            // 请求AI口数据
                            genericConnector.sendRtugetIOTVirtData(1, 2 * i, new ConnectorListener() {
                                @Override
                                public void onSuccess(boolean b) {

                                    /*   修改此处，在这里处理数据   */
                                    if (genericConnector.getRtuIOTVirtData() > 0) {
                                        switch (cache) {
                                            case 0:
                                                // 处理湿度并输出
                                                Log.i("AI1 Data", String.valueOf(6.25 * genericConnector.getRtuIOTVirtData() / 1000 - 25));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI1Val.setText(String.format("%.2f", 6.25 * genericConnector.getRtuIOTVirtData() / 1000 - 25));
                                                    }
                                                });
                                                break;
                                            case 1:
                                                // 处理温度并输出
                                                Log.i("AI2 Data", String.valueOf(4.375 * genericConnector.getRtuIOTVirtData() / 1000 - 27.5));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI2Val.setText(String.format("%.2f", 4.375 * genericConnector.getRtuIOTVirtData() / 1000 - 27.5));
                                                    }
                                                });
                                                break;
                                            case 2:
                                                // 输出AI3原始数据
                                                Log.i("AI3 Data", String.valueOf(genericConnector.getRtuIOTVirtData()));
                                                handler.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        AI3Val.setText(String.valueOf(genericConnector.getRtuIOTVirtData()));
                                                    }
                                                });
                                                break;
                                        }
                                    }
                                }

                                @Override
                                public void onFail(Exception e) {

                                }
                            });
                            TimeUnit.SECONDS.sleep(1);
                        }
                        TimeUnit.SECONDS.sleep(1);
                    } catch (Exception e) {
                        Log.e("GetAI", e.toString());
                        break;
                    }
                }
            }
        });
    }

    /**
     * 控制DO口
     *
     * @return 子线程
     */
    private Thread setDO() {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                if (RTULink) {
                    try {
                        genericConnector.sendRtuWriteData(1, Integer.parseInt(DOSpinner.getSelectedItem().toString()), Boolean.parseBoolean(DOValueSpinner.getSelectedItem().toString()), new ConnectorListener() {
                            @Override
                            public void onSuccess(boolean b) {
                                if (b) {
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(getApplicationContext(), "发送成功", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }
                            }

                            @Override
                            public void onFail(Exception e) {

                            }
                        });
                    } catch (Exception e) {
                        Log.e("Set DO Error", e.toString());
                    }
                } else {
                    try {
                        genericConnector.sendTCPSetDoVlue(1, Integer.parseInt(DOSpinner.getSelectedItem().toString()), Boolean.parseBoolean(DOValueSpinner.getSelectedItem().toString()), new ConnectorListener() {
                            @Override
                            public void onSuccess(boolean b) {
                                if (b) {
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(getApplicationContext(), "发送成功", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }
                            }

                            @Override
                            public void onFail(Exception e) {

                            }
                        });
                    } catch (Exception e) {
                        Log.e("Set DO Error", e.toString());
                    }
                }
            }
        });
    }
}
